import React, { useCallback } from "react";
import { useDocumentTitle } from "hooks";
import { useKanbans, useTasks, useReorderKanban, useReorderTask } from "server";
import KanbanColumn from "./kanban-column";
import styled from "@emotion/styled";
import SearchPanel from "./search-panel";
import { ScreenContainer } from "components/lib";
import CreateKanban from "./create-kanban";
import { Spin } from "antd";
import TaskModal from "./task-modal";
import { DragDropContext, DropResult } from "react-beautiful-dnd";
import { Drag, Drop, DropChild } from "components/drag-and-drop";
import {
  useKanbanSearchParams,
  useProjectInUrl,
  useTasksSearchParams,
} from "./util";

export const ColumnContainer = styled.div`
  display: flex;
  overflow-x: scroll;
  flex: 1;
`;

export const useDragEnd = () => {
  const { data: kanbans } = useKanbans();
  const { data: allTasks } = useTasks();
  const { mutate: reorderKanban } = useReorderKanban();
  const { mutate: reorderTask } = useReorderTask();

  return useCallback(
    ({ source, destination, type }: DropResult) => {
      if (!destination) return;

      if (type === "COLUMN") {
        const fromId = kanbans?.[source.index].id;
        const toId = kanbans?.[destination.index].id;
        if (!fromId || !toId || fromId === toId) return;

        const type = destination.index > source.index ? "after" : "before";
        reorderKanban({ fromId, referenceId: toId, type });
      }

      if (type === "ROW") {
        const fromKanbanId = +source.droppableId;
        const toKanbanId = +destination.droppableId;
        if (fromKanbanId === toKanbanId) return;

        const fromTask = allTasks?.filter((t) => t.kanbanId === fromKanbanId)[
          source.index
        ];
        const toTask = allTasks?.filter((t) => t.kanbanId === toKanbanId)[
          destination.index
        ];
        if (fromTask?.id === toTask?.id) return;

        reorderTask({
          fromId: fromTask?.id,
          referenceId: toTask?.id,
          fromKanbanId,
          toKanbanId,
          type:
            fromKanbanId === toKanbanId && destination.index > source.index
              ? "after"
              : "before",
        });
      }
    },
    [allTasks, kanbans, reorderKanban, reorderTask]
  );
};

const Kanban = () => {
  useDocumentTitle("看板列表");
  const { data: kanbans } = useKanbans(useKanbanSearchParams());
  const { data: currentProject, isLoading: kanbanLoading } = useProjectInUrl();
  const { isLoading: taskIsLoading } = useTasks(useTasksSearchParams());
  const onDragEnd = useDragEnd();
  const isLoading = kanbanLoading || taskIsLoading;

  return (
    <DragDropContext onDragEnd={onDragEnd}>
      <ScreenContainer>
        <h1>{currentProject?.name}看板</h1>
        <SearchPanel />
        {isLoading ? (
          <Spin size="large" />
        ) : (
          <ColumnContainer>
            <Drop type="COLUMN" direction="horizontal" droppableId="kanban">
              <DropChild style={{ display: "flex" }}>
                {kanbans?.map((kanban, index) => (
                  <Drag
                    draggableId={`${kanban.id}`}
                    key={kanban.id}
                    index={index}
                  >
                    <KanbanColumn key={kanban.id} kanban={kanban} />
                  </Drag>
                ))}
              </DropChild>
            </Drop>
            <CreateKanban />
          </ColumnContainer>
        )}
        <TaskModal />
      </ScreenContainer>
    </DragDropContext>
  );
};

export default Kanban;
